#!/usr/bin/perl

use DBI;
use strict;

# this script executes a few queries on the fluxdata table to flag out likely bad
# flux values

# get our command line arguments
my $output_debug=0;
for (my $i=0;$i<=$#ARGV;$i++){
    if ($ARGV[$i] eq "-D"){
	# level up debug printing
	$output_debug++;
    }
}

# database details
my $dsn="dbi:Pg:dbname=atca;host=mentok;port=5432";
my $user="postgres";
my $password="";

# Setup the database connection
my $dbh=DBI->connect($dsn,$user,$password,{ RaiseError => 0, AutoCommit => 1});

# first, flag when an uncertainty is a sizable fraction of the actual flux value
my $acceptable_flux_uncertainty=0.5;

my $fun_query="UPDATE fluxdata SET quality_flag=false WHERE ".
    "tripleamp_scatter_measured[1]>=(tripleamp_value[1]*".$acceptable_flux_uncertainty.
    ")";
if ($output_debug>0){
    print "executing query: $fun_query\n";
}
my $fun=$dbh->prepare($fun_query);
$fun->execute;

if ($output_debug>0){
    print "flagged ".$fun->rows." flux data points as bad\n";
}
$fun->finish;

# flag all points with exactly 0 uncertainty (not possible)
my $fim_query="UPDATE fluxdata SET quality_flag=false WHERE ".
    "tripleamp_scatter_measured[1]=0";
if ($output_debug>0){
    print "executing query: $fim_query\n";
}
my $fim=$dbh->prepare($fim_query);
$fim->execute;

if ($output_debug>0){
    print "flagged ".$fim->rows." flux data points as bad\n";
}
$fim->finish;

# flag all points with negative or zero flux
my $fne_query="UPDATE fluxdata SET quality_flag=false WHERE ".
    "tripleamp_value[1]<=0";
if ($output_debug>0){
    print "executing query: $fne_query\n";
}
my $fne=$dbh->prepare($fne_query);
$fne->execute;

if ($output_debug>0){
    print "flagged ".$fne->rows." flux data points as bad\n";
}
$fne->finish;

# flag all non-flux calibrators where the flux scaling factor is out of range
my $minimum_fluxscaling=0.5;
my $maximum_fluxscaling=3.0;
my $fsc_query="UPDATE fluxdata SET quality_flag=false WHERE ".
    "processed_as_flux=false AND (flux_scale_factor<".$minimum_fluxscaling.
    " OR flux_scale_factor>".$maximum_fluxscaling.")";
if ($output_debug>0){
    print "executing query: $fsc_query\n";
}
my $fsc=$dbh->prepare($fsc_query);
$fsc->execute;

if ($output_debug>0){
    print "flagged ".$fsc->rows." flux data points as bad\n";
}
$fsc->finish;

# flag all points where measured amplitude scatter is much much greater than
# the theoretical amplitude scatter
my $amp_scatter_factor=100.0;
my $fst_query="UPDATE fluxdata SET quality_flag=false WHERE ".
    "tripleamp_scatter_measured[1]>=(".$amp_scatter_factor."*".
    "tripleamp_scatter_theoretical[1])";
if ($output_debug>0){
    print "executing query: $fst_query\n";
}
my $fst=$dbh->prepare($fst_query);
$fst->execute;

if ($output_debug>0){
    print "flagged ".$fst->rows." flux data points as bad\n";
}
$fst->finish;

# flag all points where measured closure phase scatter is much much greater
# than the theoretical closure phase scatter
my $phase_scatter_factor=20.0;
my $fcp_query="UPDATE fluxdata SET quality_flag=false WHERE ".
    "closurephase_measured[1]>=(".$phase_scatter_factor."*".
    "closurephase_theoretical[1])";
if ($output_debug>0){
    print "executing query: $fcp_query\n";
}
my $fcp=$dbh->prepare($fcp_query);
$fcp->execute;

if ($output_debug>0){
    print "flagged ".$fcp->rows." flux data points as bad\n";
}
$fcp->finish;

# flag all points where the combination of closure phase scatter ratio and
# amplitude scatter ratio is greater than some cutoff
my $ratio_cutoff=25.0;
my $fra_query="UPDATE fluxdata SET quality_flag=false WHERE ".
    "sqrt((tripleamp_scatter_measured[1]/tripleamp_scatter_theoretical[1])^2 + ".
    "(closurephase_measured[1]/closurephase_theoretical[1])^2)>=".$ratio_cutoff;
if ($output_debug>0){
    print "executing query: $fra_query\n";
}
my $fra=$dbh->prepare($fra_query);
$fra->execute;

if ($output_debug>0){
    print "flagged ".$fra->rows." flux data points as bad\n";
}
$fcp->finish;


$dbh->disconnect;



